package org.jflame.context.filemanager;

import org.jflame.commons.file.FileHelper;
import org.jflame.commons.key.IDHelper;
import org.jflame.commons.model.Chars;
import org.jflame.commons.util.StringHelper;
import org.jflame.commons.util.UrlHelper;

import java.net.URI;
import java.util.Objects;
import java.util.Optional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 文件管理抽象父类,提供几个共用方法
 * 
 * @author charles.zhang
 * @param <T> 子类所需配置文件实际类型
 */
public abstract class BaseFileManager<T extends FileManagerCfg> implements IFileManager {

    protected final Logger logger = LoggerFactory.getLogger(getClass());

    protected String[] protocolPrefixs = { "http://","https://" };

    private final T config;

    public BaseFileManager(T cfg) {
        Objects.requireNonNull(cfg);
        config = cfg;
    }

    /**
     * 基于原文件扩展名生成一个新的唯一名称
     * 
     * @param ext 扩展名
     * @return
     */
    protected String createNewFileNameByExt(String ext) {
        String name = IDHelper.millisAndRandomStr(3);
        if (StringHelper.isNotEmpty(ext)) {
            if (ext.charAt(0) == '.') {
                return name + ext;
            }
            return name + '.' + ext;
        }
        return name;
    }

    /**
     * 基于原文件扩展名生成一个新的唯一名称
     * 
     * @param saveDir 文件夹,如果指定了将与新的文件名合并
     * @param fileName 原文件名
     * @return
     */
    protected String createNewFileId(String saveDir, String fileName) {
        String newName;
        if (fileName.charAt(0) == '.') {
            newName = createNewFileNameByExt(fileName);
        } else {
            newName = createNewFileNameByExt(FileHelper.getExtension(fileName, true));
        }
        if (StringHelper.isNotEmpty(saveDir)) {
            if (saveDir.charAt(0) != Chars.SLASH) {
                String baseDir = getConfig().getSavePath();
                if (StringHelper.isNotEmpty(baseDir)) {
                    return FileHelper.mergePathToUnix(baseDir, saveDir, newName);
                }
            }
            return FileHelper.mergePathToUnix(saveDir, newName);
        }
        return newName;
    }

    /**
     * 根据文件访问地址返回文件在文件系统的唯一标识
     * 
     * @param fileUrl 文件访问地址
     * @return
     */
    protected String getFileId(String fileUrl) {
        String fileKey;

        if (isProtocolStarter(fileUrl)) {
            URI uri = URI.create(fileUrl);
            fileKey = uri.getPath();
        } else {
            fileKey = fileUrl;
        }

        if (fileKey.charAt(0) == Chars.BACKSLASH || fileKey.charAt(0) == Chars.SLASH) {
            fileKey = fileKey.substring(1);
        }
        return fileKey;
    }

    protected boolean isProtocolStarter(String fileUrl) {
        return StringHelper.startsWithIgnoreCase(fileUrl, protocolPrefixs);
    }

    protected String getServerUrl() {
        return config.getServer();
    }

    /**
     * 根据文件名判断文件mimeType
     * 
     * @param fileId
     * @return
     */
    protected Optional<String> guessContentType(String fileId) {
        return FileHelper.guessMimeTypeFromName(fileId);
    }

    /**
     * 返回子类实际所需的配置类
     * 
     * @param <T>
     * @return
     */
    public T getConfig() {
        return config;
    }

    @Override
    public String toRequestUrl(String filePath) {
        if (getServerUrl() != null && !isProtocolStarter(filePath)) {
            return UrlHelper.mergeUrl(getServerUrl(), filePath);
        } else {
            return filePath;
        }
    }

}
